package com.cardbaobao.cardbabyclient.utils;

import android.text.TextUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @描述 判断字符串是否为手机号码和邮箱
 * @作者 zad
 * 2014年5月19日
 */
public class RegularUtil {
    //移动号码正则表达式
    private static final String CHINA_MOBILE_REG=
            "^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
    //联通号码正则表达式
    private static final String CHINA_UNION_REG=
            "^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
    //中国电信号码正则表达式
    private static final String CHINA_TELECOM_REG=
            "^((133)|(153)|(177)|(18[0,1,9]))\\d{8}$";

    //电子邮箱正则表达式
    private static final String EMAIL_REG=
            "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";

    /**手机号码长度*/
    public static final int PHONE_NUMBER_LENGTH=11;
    /**
     * @param number
     * @return boolean true为手机号 false不是手机号
     */
    public static boolean isPhoneNumber(String number) {
        if (number == null || number.length() != 11) {
            return false;
        } else {
            return number.matches(CHINA_MOBILE_REG)||
                    number.matches(CHINA_UNION_REG)||
                    number.matches(CHINA_TELECOM_REG);
        }
    }

    /**
     * 是否是中国移动手机号码
     * @param number 电话号码
     */
    public static boolean isChinaMobilePhone(String number){
        return number!=null&&number.matches(CHINA_MOBILE_REG);
    }

    /**
     * 是否是中国联通或者中国电信的手机号码
     * @param number 电话号码
     */
    public static boolean isUnicomOrtelecom(String number){
        return number!=null&&
                (number.matches(CHINA_UNION_REG)||number.matches(CHINA_TELECOM_REG));
    }

    /**
     * @params email boolean true为邮箱 false不是邮箱
     */
    public static boolean isEmail(String email) {
        Pattern p = Pattern.compile(EMAIL_REG);
        Matcher m = p.matcher(email);
        return m.matches();
    }

    /**
     * @描述: 是否数字与字母组合
     * @参数: str
     * @返回值: boolean
     * @创建时间：2015年2月25日上午11:04:27
     */
    public static boolean isNumberAndLetter(String str) {
        String check_str = "[0-9a-zA-Z]*";
        Pattern pzm = Pattern.compile(check_str);
        Matcher mat = pzm.matcher(str);
        return mat.matches();
    }

    /**
     * ^(\d{14}|\d{17})(\d|[xX])$
     * 检查身份证
     */
    public static boolean isIdNumber(String idNumberStr){
        String reg="^(\\d{14}|\\d{17})(\\d|[xX])$";
        Pattern pzm = Pattern.compile(reg);
        Matcher mat = pzm.matcher(idNumberStr);
        return mat.matches();
    }

    /**
     *检查姓名合法性
     * return !TextUtils.isEmpty(nameStr)&&nameStr.trim().length()>=2
     */
    public static boolean isName(String nameStr){
        return !TextUtils.isEmpty(nameStr)&&nameStr.trim().length()>=2;
    }

     /*
    当你输入信用卡号码的时候，有没有担心输错了而造成损失呢？其实可以不必这么担心，
    因为并不是一个随便的信用卡号码都是合法的，它必须通过Luhn算法来验证通过。
    该校验的过程：
    1、从卡号最后一位数字开始，逆向将奇数位(1、3、5等等)相加。
    2、从卡号最后一位数字开始，逆向将偶数位数字，先乘以2（如果乘积为两位数，则将其减去9），再求和。
    3、将奇数位总和加上偶数位总和，结果应该可以被10整除。
    例如，卡号是：5432123456788881
    则奇数、偶数位（用红色标出）分布：5432123456788881
    奇数位和=35
    偶数位乘以2（有些要减去9）的结果：1 6 2 6 1 5 7 7，求和=35。
    最后35+35=70 可以被10整除，认定校验通过。
    请编写一个程序，从键盘输入卡号，然后判断是否校验通过。通过显示：“成功”，否则显示“失败”。
    比如，用户输入：356827027232780
    程序输出：成功
    */

    /**
     * 校验银行卡卡号
     * @param cardNumber
     * @return
     */
    public static boolean checkBankCard(String cardNumber) {
        char bit = getBankCardCheckCode(cardNumber.substring(0, cardNumber.length() - 1));
        if(bit == 'N'){
            return false;
        }
        return cardNumber.charAt(cardNumber.length() - 1) == bit;
    }

    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     * @param nonCheckCodeCardId
     * @return
     */
    private static char getBankCardCheckCode(String nonCheckCodeCardId){
        if(nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0
                || !nonCheckCodeCardId.matches("\\d+")) {
            //如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int luhmSum = 0;
        for(int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if(j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0');
    }
}
